<?php

/************************************************************
	Connecteur Atos/SIPS pour Prestashop
	par Damien VERON - http://www.capillotracteur.fr
	sous licence GNU/GPL v3
 ************************************************************/
class tgg_atos extends PaymentModule {
	private $_confVars = array(
		'DEMO',
		'BANK',
		'MERCHANT_ID',
		'LOGO_NAME',
		'OS_PAYMENT_SUCCESS',
		'FALLBACK_CURRENCY',
		'PAYMENT_MEANS',
		'INT_MIN_TID',
		'BIN_PATH',
		'PARAM_PATH',
		'LOG_PATH',
		'LOGO_PATH',
		'IMG_PATH',
		'BOOL_RESPONSE_LOG_TXT',
		'BOOL_RESPONSE_LOG_CSV',
		'BOOL_BINARIES_IN_PATH'
	);
	private $_banks = array(
		'cyberplus' => 'CyberPlus - Banque Populaire',
		'etransactions' => 'E-Transactions - Crédit Agricole',
		'elysnet' => 'ElysNet - CCF/HSBC',
		'mercanet' => 'Mercanet - BNP',
		'scelliusnet' => 'ScelliusNet - La Banque Postale',
		'sherlocks' => 'Sherlocks - LCL',
		'sogenactif' => 'Sogenactif - Société Générale',
		'webaffaires' => 'WebAffaires - Crédit du Nord'
	);
	private $_demoCertificates = array(  
		'cyberplus' => '038862749811111',
		'etransactions' => '013044876511111',
		'elysnet' => '014102450311111',
		'mercanet' => '082584341411111',
		'scelliusnet' => '014141675911111',
		'sherlocks' => '014295303911111',
		'sogenactif' => '014213245611111',
		'webaffaires' => '014022286611111'
	);
	private $_currencies = array(
		'EUR' => array('978',2),
		'USD' => array('840',2),
		'CHF' => array('756',2),
		'GBP' => array('826',2),
		'CAD' => array('124',2),
		'JPY' => array('392',0),
		'MXN' => array('484',2),
		'TRY' => array('949',2),
		'AUD' => array('036',2),
		'NZD' => array('554',2),
		'NOK' => array('578',2),
		'BRL' => array('986',2),
		'ARS' => array('032',2),
		'KHR' => array('116',2),
		'TWD' => array('901',2),
		'SEK' => array('752',2),
		'DKK' => array('208',2),
		'KRW' => array('410',0),
		'SGD' => array('702',2),
		'XPF' => array('953',0),
		'XOF' => array('952',0)
	);
	private $_responseFields = array(
		'merchant_id',
		'merchant_country',
		'amount',
		'transaction_id',
		'payment_means',
		'transmission_date',
		'payment_time',
		'payment_date',
		'response_code',
		'payment_certificate',
		'authorisation_id',
		'currency_code',
		'card_number',
		'cvv_flag',
		'cvv_response_code',
		'bank_response_code',
		'complementary_code',
		'complementary_info',
		'return_context',
		'caddie',
		'receipt_complement',
		'merchant_language',
		'language',
		'customer_id',
		'order_id',
		'customer_email',
		'customer_ip_address',
		'capture_day',
		'capture_mode',
		'data'
	);
	
	private $_responseFieldsLoggedInOrder = array(
		'merchant_id',
		'transaction_id',
		'transmission_date',
		'payment_time',
		'payment_date',
		'response_code',
		'payment_certificate',
		'authorisation_id',
		'currency_code',
		'cvv_flag',
		'cvv_response_code',
		'bank_response_code',
		'complementary_code',
		'complementary_info',
		'return_context',
		'receipt_complement',
		'merchant_language',
		'language',
		'customer_email',
		'customer_ip_address',
		'capture_day',
		'capture_mode'
	);
	
	public function __construct() {
		$this->name = 'tgg_atos';
		$this->tab = 'Payment';
		$this->version = '1.0';
		$this->currencies_mode = 'checkbox';
		parent::__construct();
		$this->displayName = $this->l('SIPS/ATOS');
		$this->description = $this->l('SIPS/ATOS payment module by TrogloGeek', 'tgg_atos');
		$this->confirmUninstall = $this->l('If you uninstall this module, all configuration related to ATOS payment will be deleted, including any production certificate file you could have uploaded. Only logfiles are left in place for security reasons. If you intended only to stop using ATOS for a while and use it again later you should consider disabling this module instead of uninstalling it. Uninstall it anyway ?');
	}
	
	public function install() {
		$bankReturnHook = new Hook();
		$bankReturnHook->name = 'tggAtosBankReturn';
		$orderConfirmHook = new Hook();
		$orderConfirmHook->name = 'tggAtosOrderConfirm';
		return parent::install()
			&& $this->_setDefaults()
			&& $this->_writeConf()
			&& $this->registerHook('payment')
			&& $this->registerHook('paymentReturn')
			&& Db::getInstance()->Execute('
					CREATE TABLE `'._DB_PREFIX_.$this->name.'_transactions_today` (
						`date`  date NOT NULL,
						`atos_transaction_id`  mediumint(9) UNSIGNED NOT NULL AUTO_INCREMENT,
						PRIMARY KEY (`date`, `atos_transaction_id`)
					)
					ENGINE=MyISAM
					AUTO_INCREMENT=1
					CHECKSUM=0
					ROW_FORMAT=FIXED
				;')
			&& $bankReturnHook->add()
			&& $orderConfirmHook->add();
	}
	
	public function uninstall() {
		try {
			$bankReturnHook = new Hook(Hook::get('tggAtosBankReturn'));
			$bankReturnHook->delete();
		} catch (Exception $e) {
		}
		try {
			$orderConfirmHook = new Hook(Hook::get('tggAtosOrderConfirm'));
			$orderConfirmHook->delete();
		} catch (Exception $e) {
		}
		//pathfile, parmcom & certif
		$path = $this->_getPath('PARAM');
		if (is_dir($path)) {
			if (file_exists($path.'pathfile')) unlink($path.'pathfile');
			@chdir($path);
			$prefix = 'parmcom.';
			$prefix_length = strlen($prefix);
			$files = glob($prefix.'*');
			foreach ($files as $file) {
				$file = substr($file, $prefix_length);
				if (preg_match('/^[0-9]+$/', $file))
					unlink($path.$prefix.$file);
			}
			$certif_ids = $this->_getMerchantIdList();
			foreach ($certif_ids as $id) @unlink($path.'certif.fr.'.$id);
		}
		//transaction_id table
		Db::getInstance()->Execute('DROP TABLE IF EXISTS `'._DB_PREFIX_.$this->name.'_transactions_today`;');
		//Config vars
		foreach ($this->_confVars as $k)
			$this->_unset($k);
		return parent::uninstall();
	}
	
	public function getContent(){
		global $smarty;
		if (Tools::isSubmit('renameCertif') && ($mechant_id = Tools::getValue('merchant_id'))) {
			rename($this->_getPath('PARAM').'CERTIF~1', $this->_getPath('PARAM').'certif.fr.'.$mechant_id);
			$this->_set('MERCHANT_ID', $mechant_id);
			$this->_writeConf();
		} elseif (is_file($this->_getPath('PARAM').'CERTIF~1')) {
			return $this->display(__FILE__, 'tpl/'.$this->name.'-back-ask-merchant-id.tpl');
		}
		$errors = array();
		$display_advanced_conf = false;
		if (Tools::isSubmit('updateConf')) {
			foreach ($this->_confVars as $k) {
				if (strpos($k, 'BOOL_') === 0) {
					if (Tools::getIsset(strtolower($k)) && Tools::getValue(strtolower($k))) {
						$this->_set($k, 1);
					} else {
						$this->_set($k, 0);
					}
				} elseif (strpos($k, 'INT_') === 0) {
					if (Tools::getIsset(strtolower($k))) {
						$this->_set($k, intval(Tools::getValue(strtolower($k))));
					} else {
						$this->_set($k, 0);
					}
				} else {
					if (Tools::getIsset(strtolower($k)))
						$this->_set($k, Tools::getValue(strtolower($k)));
				}
			}
			if (is_uploaded_file($_FILES['new_certificate']['tmp_name'])) 
				if (!$this->_uploadCertificate())
					$errors[] = $this->l('Unable to write certificate file, check permitions on param dir');
			if (!$this->_writeConf())
				$errors[] = $this->l('Unable to write configuration file, check permitions on param dir');
		} elseif (Tools::isSubmit('defaultConf')) {
			$this->_setDefaults();
			if (!$this->_writeConf())
				$errors[] = $this->l('Unable to write configuration file, check permitions on param dir');
		}
		//Check paths
		if (! $this->_get('BOOL_BINARIES_IN_PATH')) {
			if (! is_dir($this->_getPath('BIN'))) {
				$errors[] = $this->l('Binaries path points to a non existing dir or the dir hasn\'t enough rights');
			} elseif (! $this->_checkBinariesPath()) {
				$errors[] = $this->l('Binaries not found');
			}
		}
		if (! is_dir($param_path = $this->_getPath('PARAM')))
			$errors[] = $this->l('Parameters files path points to a non existing dir or the dir hasn\'t enough rights');
		if (strlen($param_path) > 54)
			$errors[] = $this->l('Parameters files path is too long, 54 characters max');
		if (! is_dir($this->_getPath('LOG')))
			$errors[] = $this->l('Logfiles path points to a non existing dir or the dir hasn\'t enough rights');
		if (! strlen($this->_getPath('LOGO')))
			$errors[] = $this->l('Cards logos URL is needed');
		if (! strlen($this->_getPath('IMG')))
			$errors[] = $this->l('Banks logos URL is needed');
		$min_tid = intval($this->_get('INT_MIN_TID'));
		if (($min_tid < 1) || ($min_tid > 999999)) {
			$this->_set('INT_MIN_TID', 1);
			$errors[] = $this->l('Minimum transaction ID you specified was invalid, must be an integer between 1 and 999999.');
		}
		if (count($errors)) $display_advanced_conf = true;
		if (!Currency::getIdByIsoCode($this->_get('FALLBACK_CURRENCY')))
			$errors[] = $this->l('Fallback currency isn\'t set or doesn\'t exist anymore');
		
		if (strlen($this->_get('LOGO_NAME')) == 0) $errors[] = $this->l('Merchant logo filename is required');
		if (!$this->_get('DEMO') && (!$this->_get('MERCHANT_ID'))) $errors[] = $this->l('Merchant id is required');
		foreach ($this->_confVars as $k)
			$smarty->assign(strtolower($k), $this->_get($k));
		$smarty->assign(array(
			'banks' => $this->_banks,
			'errors' => $errors,
			'display_advanced_conf' => $display_advanced_conf,
			'merchant_ids' => $this->_getMerchantIdList(),
			'currencies' => $this->_getCurrencies(),
			'order_states' => OrderState::getOrderStates(_USER_ID_LANG_),
		));
		return $this->display(__FILE__, 'tpl/'.$this->name.'-back-default.tpl');
	}
	
	public function hookPayment($params){
		global $smarty;
		$protocol = (Configuration::get('PS_SSL_ENABLED') OR (isset($_SERVER['HTTPS']) AND strtolower($_SERVER['HTTPS']) == 'on')) ? 'https://' : 'http://';
		$module_base_url = $protocol.$_SERVER['SERVER_NAME']._MODULE_DIR_;
		$smarty->assign(array(
			'href' => $module_base_url.$this->name.'/tpl/'.$this->name.'-payment-redirect.php',
			'bank' => $this->_get('BANK'),
			'canProcess' => (Db::getInstance()->getValue('SELECT MAX(`atos_transaction_id`) FROM '._DB_PREFIX_.$this->name.'_transactions_today` WHERE date = \''.date('Y-m-d').'\'') < 999999)
		));
		return $this->display(__FILE__, 'tpl/'.$this->name.'-front-hookPayment.tpl');
	}
	
	public function hookPaymentReturn() {
		return $this->display(__FILE__, 'tpl/'.$this->name.'-front-order-confirmation.tpl');
	}
	
	public function getPaymentForm(&$amount, &$payment_currency) {
		global $cart, $cookie;
		//check currency and convert price
		$currencies = $this->_getCurrencies();
		$payment_currency = NULL;
		foreach ($currencies as $currency)
			if ($currency['id_currency'] == $cart->id_currency) {
				$payment_currency = $currency;
				break;
			}
		if (is_null($payment_currency)) $payment_currency = $this->_getFallBackCurrency();
		
		if ($payment_currency['id_currency'] != $cart->id_currency) {
			$cookie->id_currency = $payment_currency['id_currency'];
			$cart->id_currency = $payment_currency['id_currency'];
			$cart->update();
			//Currency updated, refresh to avoid bugs
			Tools::redirectLink($_SERVER['REQUEST_URI']);
		}

		$amount = $cart->getOrderTotal();
		if (version_compare(_PS_VERSION_, '1.3.1') >= 0) {
			$amount = Tools::ps_round($amount, $payment_currency['decimals']);
		} else {
			$amount = round($amount, $payment_currency['decimals']);
		}
		$atos_amount = round($amount * pow(10, intval($payment_currency['decimals'])));
		
		$Customer = new Customer($cart->id_customer);
		$Lang = new Language(_USER_ID_LANG_);
		$cmd = $this->_getPath('BIN').'request';
		$params = array(
			'amount' => $atos_amount,
			'currency_code' => $payment_currency['atos_code'],
			'customer_id' => $Customer->id,
			'customer_email' => $Customer->email,
			'customer_ip_address' => $_SERVER['REMOTE_ADDR'],
			'language' => $Lang->iso_code,
			'merchant_id' => $this->_getMerchantId(),
			'order_id' => $cart->id,
			'transaction_id' => $this->_generateTransactionID()
		);
		$output = $this->_call('request', $params);
		if (is_array($output)) 
			return $output[0];
		return false;
	}
	
	public function decryptResponse($data) {
		$output = $this->_call('response', array('message' => $data));
		if (!is_array($output)) 
			return false;
		$response = array();
		foreach ($output as $k => $v) $response[$this->_responseFields[$k]] = $v;
		return (object)$response;
	}
	
	public function processResponse($Response, &$Customer, &$Order) {
		global $cookie, $cart;
		$Response->caller_ip_address = $_SERVER['REMOTE_ADDR'];
		$this->_logResponse($Response);
		$cart = new Cart($Response->order_id);
		if (!Validate::isLoadedObject($cart))
			return $this->_invalid_response($this->l('Cart ID returned in id_order field does not exist'), $Response);
		$Customer = new Customer($Response->customer_id);
		if (!Validate::isLoadedObject($Customer))
			return $this->_invalid_response($this->l('Customer ID returned in id_customer field does not exist'), $Response);
		if ($cart->id_customer != $Customer->id)
			return $this->_invalid_response($this->l('Cart which ID has been returned in field id_order does not belong to Customer which ID has been returned in field id_customer'), $Response);
		$currency_used = NULL;
		foreach ($this->_currencies as $k => $v)
			if ($v[0] == $Response->currency_code) {
				$currency_used = $k;
				break;
			}
		if (is_null($currency_used))
			return $this->_invalid_response($this->l('Unknown currency_code'), $Response);
		$Currency = new Currency(Currency::getIdByIsoCode($currency_used));
		if (!Validate::isLoadedObject($Currency))
			return $this->_invalid_response($this->l('ISO Currency Code ').$currency_used.$this->l(' isn\'t implemented in Prestashop, can\'t process order.'), $Response);
		Module::hookExec('tggAtosBankReturn', array('Response' => $Response, 'Cart' => $cart, 'Customer' => $Customer));
		if (!($Response->response_code === '00'))
			return false;
		if (!$cart->OrderExists()) {
			if ($cart->id_currency != $Currency->id) {
				$cart->id_currency = $Currency->id;
				$cookie->id_currency = $Currency->id;
				$cart->update();
			}
			if ($this->validateOrder(
				$cart->id,
				$this->_get('OS_PAYMENT_SUCCESS'),
				$Response->amount / pow(10, $this->_currencies[$currency_used][1]),
				$this->displayName,
				$this->_makeOrderMessage($Response),
				array(),
				($cart->id_currency != $Currency->id) ? $Currency->id : NULL,
				false
			)) {
				$Order = new Order($this->currentOrder);
				Module::hookExec('tggAtosOrderConfirm', array('Response' => $Response, 'Cart' => $cart, 'Customer' => $Customer, 'Order' => $Order));
			} else {
				return false;
			}
		}
		$Order = new Order(Order::getOrderByCartId($cart->id));
		return true;
	}
	
	protected function _get($varname) {
		return Configuration::get(strtoupper($this->name).'_'.$varname);
	}
	
	protected function _getPath($varname) {
		$path = $this->_get($varname.'_PATH');
		if ($path[strlen($path)-1] != '/') $path .= '/';
		return $path;
	}
	
	protected function _getMerchantId() {
		if ($this->_get('DEMO')) {
			return $this->_demoCertificates[$this->_get('BANK')];
		} else {
			return $this->_get('MERCHANT_ID');
		}
	}
	
	protected function _getMerchantIdList() {
		$prefix = 'certif.fr.';
		$prefix_length = strlen($prefix);
		$path = $this->_getPath('PARAM');
		if (!is_dir($path)) return false;
		chdir($path);
		$files = glob($prefix.'*');
		$codes = array();
		foreach ($files as $file) {
			$code = substr($file, $prefix_length);
			if (!in_array($code, $this->_demoCertificates))
				$codes[] = $code;
		}
		return $codes;
	}
	
	protected function _getCurrencies() {
		$currencies = $this->getCurrency();
		foreach ($currencies as $k => $currency) {
			if (!array_key_exists($currency['iso_code'], $this->_currencies)) {
				unset($currencies[$k]);
			} else {
				$currencies[$k]['atos_code'] = $this->_currencies[$currency['iso_code']][0];
				$currencies[$k]['decimals'] = $this->_currencies[$currency['iso_code']][1];
			}
		}
		return $currencies;
	}
	
	protected function _getFallBackCurrency() {
		$currency = Currency::getCurrency(Currency::getIdByIsoCode($this->_get('FALLBACK_CURRENCY')));
		$currency['atos_code'] = $this->_currencies[$currency['iso_code']][0];
		$currency['decimals'] = $this->_currencies[$currency['iso_code']][1];
		return $currency;
	}

	protected function _set($varname, $value) {
		return Configuration::updateValue(strtoupper($this->name).'_'.$varname, $value);
	}
	
	protected function _setDefaults() {
		$path = dirname(__FILE__);
		if (($path[strlen($path)-1] != DIRECTORY_SEPARATOR) && ($path[strlen($path)-1] != '/')) $path .= DIRECTORY_SEPARATOR;
		$defaults = array(
			'DEMO' => '1',
			'BANK' => 'cyberplus',
			'MERCHANT_ID' => '',
			'LOGO_NAME' => 'merchant.gif',
			'OS_PAYMENT_SUCCESS' => _PS_OS_PAYMENT_,
			'FALLBACK_CURRENCY' => 'EUR',
			'PAYMENT_MEANS' => 'CB,2,VISA,2,MASTERCARD,2',
			'INT_MIN_TID' => 1,
			'BIN_PATH' => $path.'bin/',
			'PARAM_PATH' => $path.'param/',
			'LOG_PATH' => $path.'log/',
			'LOGO_PATH' => $this->_path.'logo/',
			'IMG_PATH' => $this->_path.'images/',
			'BOOL_RESPONSE_LOG_TXT' => 1,
			'BOOL_RESPONSE_LOG_CSV' => 0,
			'BOOL_BINARIES_IN_PATH' => 0
		);
		$retval = true;
		foreach ($defaults as $k => $v) $retval = $this->_set($k, $v) && $retval;
		return $retval;
	}
	
	protected function _unset($varname) {
		return Configuration::deleteByName(strtoupper($this->name).'_'.$varname);
	}
	
	protected function _uploadCertificate() {
		try {
			$path = $this->_getPath('PARAM');
			if (!is_dir($path)) return false;
			$F = $_FILES['new_certificate'];
			if (preg_match('/^certif\.fr\.([0-9]+)$/', $F['name'], $pattern_result)) {
				$name = $F['name'];
				$this->_set('MERCHANT_ID', $pattern_result[1]);
				$this->_writeConf();
			} else {
				$name = 'CERTIF~1';
			}
			return move_uploaded_file($F['tmp_name'], $path.$name);
		} catch (Exception $e) {
			return false;
		}	
	}
	
	protected function _writeConf() {
		$protocol = (Configuration::get('PS_SSL_ENABLED') OR (isset($_SERVER['HTTPS']) AND strtolower($_SERVER['HTTPS']) == 'on')) ? 'https://' : 'http://';
		$module_base_url = $protocol.$_SERVER['SERVER_NAME']._MODULE_DIR_.$this->name.'/';
		$param_path = $this->_getPath('PARAM');
		if (!is_dir($param_path)) return false;
		$merchant_id = $this->_getMerchantId();
		if ($merchant_id === false || !strlen($merchant_id)) return true;
		try {
			//Ecriture du pathfile
			if (! $F = @fopen($param_path.'pathfile', 'w')) return false;
			fwrite($F, 'DEBUG!NO!'."\n");
			fwrite($F, 'D_LOGO!'.$this->_getPath('LOGO').'!'."\n");
			fwrite($F, 'F_CERTIFICATE!'.$param_path.'certif!'."\n");
			fwrite($F, 'F_PARAM!'.$param_path.'parmcom!'."\n");
			fwrite($F, 'F_DEFAULT!'.$param_path.'parmcom.'.$this->_get('BANK').'!');
			fclose($F);
			//Ecriture du parmcom
			if (! $F = @fopen($param_path.'parmcom.'.$this->_getMerchantId(), 'w')) return false;
			fwrite($F, 'LOGO!'.$this->_get('LOGO_NAME').'!'."\n");
			fwrite($F, 'RETURN_URL!'.$module_base_url.'payment-return.php!'."\n");
			fwrite($F, 'AUTO_RESPONSE_URL!'.$module_base_url.'payment-autoresponse.php!'."\n");
			fwrite($F, 'CANCEL_URL!'.$module_base_url.'payment-return.php!'."\n");
			fwrite($F, 'MERCHANT_COUNTRY!fr!'."\n");
			fwrite($F, 'PAYMENT_MEANS!'.$this->_get('PAYMENT_MEANS').'!'."\n");
			fclose($F);
			return true;
		} catch (Exception $e) {
			return false;
		}
	}	
	
	protected function _checkBinariesPath() {
		$path = $this->_getPath('BIN');
		return is_file($path.'response') && is_file($path.'request');
	}
	
	/* Retourne un ID de transaction unique sur la journée */
	protected function _generateTransactionID() {
		$DB = Db::getInstance();
		$today = date('Y-m-d');
		//Nettoyage des ID des jours précédents
		$DB->Execute('DELETE FROM `'._DB_PREFIX_.$this->name.'_transactions_today` WHERE date < \''.$today.'\'');
		//Réservation d'un ID sur la journée
		$DB->Execute('INSERT INTO `'._DB_PREFIX_.$this->name.'_transactions_today` SET date = \''.$today.'\'');
		$min_tid = intval($this->_get('INT_MIN_TID'));
		$tid = intval($DB->Insert_ID());
		if ($tid < $min_tid) {
			$DB->Execute('INSERT INTO `'._DB_PREFIX_.$this->name.'_transactions_today` SET date = \''.$today.'\', atos_transaction_id = '.intval($min_tid));
			$tid = intval($DB->Insert_ID());
			if (!$tid) { 
				$DB->Execute('INSERT INTO `'._DB_PREFIX_.$this->name.'_transactions_today` SET date = \''.$today.'\'');
				$tid = intval($DB->Insert_ID());
			}
			return $tid;
		} else {
			return $tid;
		}
	}
	
	protected function _call($exename, $params) {
		$cmd = ($this->_get('BOOL_BINARIES_IN_PATH') ? '' : $this->_getPath('BIN')).$exename;
		$params['pathfile'] = $this->_getPath('PARAM').'pathfile';
		foreach ($params as $k => $v)
			$cmd .= ' ' . escapeshellarg($k.'='.$v);
		$output = trim(exec(escapeshellcmd($cmd).' 2>&1', $longoutput, $status));
		if ($status == 0) {
			$output = explode('!', substr($output, 1, -1));
			if ($output[0] == '0') {
				return array_slice($output, 2);
			} else {
				$this->_debug_mail($this->l('Error returned when calling').' '.$exename, 'binary-returned-error', array('{error}' => $output[1], '{exename}' => $exename));
			}
		} else {
			$this->_debug_mail($this->l('Error returned when calling').' '.$exename, 'binary-returned-error', array('{error}' => '('.$status.'): '.implode("\n", $longoutput), '{exename}' => $exename));
		}
		return false;
	}
	
	protected function _debug_mail($title, $tplname, $vars) {
		Mail::Send(Language::getIdByIso('fr'), $tplname, '['.$this->name.'] '.$title, $vars, Configuration::get('PS_SHOP_EMAIL'), $this->l('Administrator').' - '.Configuration::get('PS_SHOP_NAME'), NULL, NULL, NULL, NULL, dirname(__FILE__).'/mails/');
	}
	
	protected function _invalid_response($error, $Response) {
		$response_txt = '';
		$Response = (array)$Response;
		foreach ($Response as $k => $v)
			$response_txt .= $k . ': ' . $v . "\n";
		$response_html = nl2br($response_txt);
		$this->_debug_mail($this->l('Invalid response'), 'invalid-response', array(
			'{error}' => $error,
			'{response_txt}' => $response_txt,
			'{response_html}' => $response_html
		));
		return false;
	}
	
	protected function _makeOrderMessage($Response) {
		$retval = $Response->payment_means . "\n" 
			. str_replace('.', ' #### #### ##', $Response->card_number) . "\n";
		foreach ($this->_responseFieldsLoggedInOrder as $k)
			$retval .= $k . ': ' . $Response->$k . "\n";
		return $retval;
	}
	
	protected function _logResponse($Response) {
		try {
			$response = (array)$Response;
			if ($this->_get('BOOL_RESPONSE_LOG_TXT')) {
				if ($F = fopen($this->_getPath('LOG').'response-'.date('Y-m-d').'.txt', 'a')) {
					fwrite($F, '-----------------------------------'."\n");
					foreach ($response as $k => $v)
						fwrite($F, $k.': '.$v."\n");
				}
				fclose($F);
			}
			$F = NULL;
			if ($this->_get('BOOL_RESPONSE_LOG_CSV')) {
				$fname = $this->_getPath('LOG').'response-'.date('Y-m-d').'.csv';
				$header = !file_exists($fname);
				if ($F = fopen($fname, 'a')) {
					if ($header)
						fputcsv($F, array_keys($response), ';', '"');
					fputcsv($F, $response, ';', '"');
				}
				fclose($F);
			}
		} catch (Exception $e) {return false;}
	}
}

?>